package com.ruoyi.ex.service.impl;

import java.util.*;

import cn.hutool.core.bean.BeanUtil;
import com.doudou.core.container.ListUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.doudou.core.lang.ObjUtil;
import com.ruoyi.common.core.redis.RedisCache;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.value.Values;
import com.ruoyi.ex.mapper.ExQuestionBankMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.ex.mapper.ExQuestionMapper;
import com.ruoyi.ex.domain.ExQuestion;
import com.ruoyi.ex.service.IExQuestionService;

/**
 * 题目Service业务层处理
 *
 * @author zzx
 * @date 2023-03-23
 */
@Service("exQuestionServiceImpl")
@Slf4j
public class ExQuestionServiceImpl implements IExQuestionService {
    @Autowired private ExQuestionMapper exQuestionMapper;
    @Autowired private ExQuestionBankMapper exQuestionBankMapper;

    @Autowired private RedisCache redis;

    /**
     * 加载全部题目到缓存
     */
    @Override
    public void cacheQuestions() {
        exQuestionBankMapper.selectExQuestionBankByIdAllId().forEach(this::cacheQuestions);
    }

    /**
     * 更新改题库下的缓存
     * @param bankId 题库
     */
    @Override
    public void cacheQuestions(Long bankId){
        try{
            Map<String,ExQuestion> map = new HashMap<>();
            String key = Values.EX_BANK_QUESTION_MAP + bankId;
            redis.deleteObject(key);
            for (ExQuestion exQuestion : exQuestionMapper.selectExQuestionList(ExQuestion.builder().bankId(bankId).build())) {
                try{
                    map.put(exQuestion.getId()+"",exQuestion);
                }catch (Exception e){
                    log.error("",e);
                }
            }
            redis.setCacheMap(Values.EX_BANK_QUESTION_MAP_KEY,map);//存放全量
            redis.setCacheMap(key,map);//单个题库存放
        }catch (Exception e){
            log.error("",e);
        }
    }

    /**
     * 随机获取题目
     */
    @Override
    public List<Long> randomGetIds(Map<Long, Integer> selectQuestions) {
        List<Long> list = ListUtil.list(true);
        selectQuestions.forEach((bankId,count)->{
            if (count > 0){
                //从缓存中取出改题库下的题目
                List<ExQuestion> exQuestions;
                Map<String, Object> cacheMap = redis.getCacheMap(Values.EX_BANK_QUESTION_MAP + bankId);
                if (ObjectUtil.isNotEmpty(cacheMap)){
                    exQuestions = JSONUtil.toList(JSONUtil.parseArray(cacheMap.values()),ExQuestion.class);
                }else{
                    exQuestions = exQuestionMapper.selectExQuestionList(ExQuestion.builder().bankId(bankId).build());
                }
                //随机生成 exQuestions.size 的 count 个下标
                Set<Integer> indexs = new HashSet<>(count);
                int limit = exQuestions.size();
                while (indexs.size() < count){
                    //范围在长度之内
                    int index = RandomUtil.randomInt(0,limit);
                    indexs.add(index);
                }
                for (Integer index : indexs) {
                    list.add(exQuestions.get(index).getId());
                }
            }
        });
        return list;
    }

    @Override
    public List<ExQuestion> selectExQuestionByIds(List<Long> ids) {
        List<ExQuestion> list = ListUtil.list(true);
        for (Long id : ids) {
            list.add(selectExQuestionById(id));
        }
        return list;
    }

    @Override
    public List<ExQuestion> selectExQuestionListByCourseWare(Long wareId) {
        return exQuestionMapper.selectExQuestionListByCourseWare(wareId);
    }

    @Override
    public List<Long> selectExQuestionIdsByCourseWare(Long wareId) {
        return exQuestionMapper.selectExQuestionIdsByCourseWare(wareId);
    }

    @Override
    public List<Long> selectIdsByBankId(Long bankId) {
        return exQuestionMapper.selectAllByBankId(bankId);
    }


    /**
     * 查询题目
     *
     * @param id 题目主键
     * @return 题目
     */
    @Override
    public ExQuestion selectExQuestionById(Long id) {
        try{
            ExQuestion exQuestion = redis.getCacheMapValue(Values.EX_BANK_QUESTION_MAP_KEY, id + "");
            if (ObjUtil.isEmpty(exQuestion)){
                exQuestion = exQuestionMapper.selectExQuestionById(id);
                redis.setCacheMapValue(Values.EX_BANK_QUESTION_MAP_KEY,exQuestion.getId()+"",exQuestion);
            }
            return exQuestion;
        }catch (Exception e){
            log.error("",e);
        }
        return exQuestionMapper.selectExQuestionById(id);
    }

    /**
     * 查询题目列表
     *
     * @param exQuestion 题目
     * @return 题目
     */
    @Override
    public List<ExQuestion> selectExQuestionList(ExQuestion exQuestion) {
        return exQuestionMapper.selectExQuestionList(exQuestion);
    }

    /**
     * 新增题目
     *
     * @param exQuestion 题目
     * @return 结果
     */
    @Override
    public int insertExQuestion(ExQuestion exQuestion) {
        exQuestion.parseOptions();
        exQuestion.setCreateTime(DateUtils.getNowDate());
        return exQuestionMapper.insertExQuestion(exQuestion);
    }

    /**
     * 修改题目
     *
     * @param exQuestion 题目
     * @return 结果
     */
    @Override
    public int updateExQuestion(ExQuestion exQuestion) {
        exQuestion.parseOptions();
        return exQuestionMapper.updateExQuestion(exQuestion);
    }

    /**
     * 批量删除题目
     *
     * @param ids 需要删除的题目主键
     * @return 结果
     */
    @Override
    public int deleteExQuestionByIds(Long[] ids) {
        try{
            Set<Long> bankIds = new HashSet<>();
            for (Long id : ids) {
                ExQuestion exQuestion = selectExQuestionById(id);
                bankIds.add(exQuestion.getBankId());
                //删除redis中的数据
                redis.deleteCacheMapValue(Values.EX_BANK_QUESTION_MAP_KEY,id+"");
            }
            //更新redis
            for (Long bankId : bankIds) {
                cacheQuestions(bankId);
            }
        }catch (Exception e){
            log.error("",e);
        }
        return exQuestionMapper.deleteExQuestionByIds(ids);
    }

    /**
     * 删除题目信息
     *
     * @param id 题目主键
     * @return 结果
     */
    @Override
    public int deleteExQuestionById(Long id) {
        return exQuestionMapper.deleteExQuestionById(id);
    }

    @Override
    public int insertExQuestionAll(List<ExQuestion> exQuestionList) {
        return exQuestionMapper.insertExQuestionAll(exQuestionList);
    }

    @Override
    public int selectExQuestionTotalByBankId(Long bankId) {
        return exQuestionMapper.selectCountByBankId(bankId);
    }
}
